{
	class GatewayAgent extends JsonRpcAgent {
		/**
		 * 构造函数
		 * @param {String} addr     网关 JsonRpc 连接地址
		 * @param {String} target   网关 JsonRpc 目标
		 * @param {Object} gateway  网关信息
		 */
		constructor(addr, target, gateway) {
			super(addr, target, gateway.token);
			let me = this;
			
			this.gateway = gateway;
			
			// 应用层事件回调函数
			this.appEventHandler = null;
			
			// 注册核心对象事件(类型名称为"handleEvent")处理函数
			this.registerNotifyHandler("handleEvent", function(event) {
				console.log("收到事件：" + event.params);
								
				// 回调应用层事件处理函数
				if(me.appEventHandler) { 
					try {
						// !!!注意：一定要通过 try-catch 保护起来，否则可能因为回调函数内部错误导致 JsonRpc 连接中断！
						me.appEventHandler(me.gateway, event.params); 
					} catch(e) {
						console.log("回调应用层事件处理函数时出错！" + Object.toString(e));
					}
				}
			});			
			
			// 当前页面关注的核心对象映射表
			// key: oid
			// value: 核心对象的 ObjInfo
			// 应用如：objs[12].title
			this.caredObjs = {};
		}

		close() {
			if (this.rpcLink) {
				this.rpcLink.close();
			}
		}

		setTarget(target) {
			this.rpctarget = target;
		}
		
		/**
		 * 设置应用层事件回调函数
		 * @param {Function} appEventHandler 收到订阅的事件时，会回调此函数 appEventHandler(gatewayInfo, eventInfo)
		 */
		setAppEventHandler(appEventHandler) {
			this.appEventHandler = appEventHandler;
		}
		
		/**
		 * 设置当前页面关注的核心对象列表(每条记录是一个核心对象的 ObjInfo)
		 * @return {Promise} 返回一个异步结果对象
		 */
		setCaredObjs(newObjs) {
			// 当前的对象表
			let oldObjs = this.caredObjs;
			// 要添加的对象表
			let addObjs = [];
			// 要删除的对象表
			let delObjs = [];
			
			for(let oid in newObjs) {
				// 如果新的对象在老列表中不存在，则表示要添加它（可能要订阅对应的事件）
				if(!oldObjs[oid]) { addObjs.push(newObjs[oid]); }
			}
			for(let oid in oldObjs) {
				// 如果老的对象在新列表中不存在，则表示要移除它（可能要取消订阅对应的事件）
				if(!newObjs[oid]) { delObjs.push(oldObjs[oid]); }
			}
			
			// 保存新的列表
			this.caredObjs = newObjs;
			
			// 更新订阅
			return this.updateSubscribe(addObjs, delObjs);
		}
		
		/**
		 * 订阅本网关的核心对象的上报事件
		 * @param {ObjInfo[]} addObjs 要订阅的核心对象列表，对象本身及对象下属子对象的事件将会被订阅
		 * @param {ObjInfo[]} delObjs 要取消订阅的核心对象的列表，对象及其下属子对象的事件将会被取消订阅
		 * @return {Promise} 返回一个异步结果对象
		 */
		updateSubscribe(addObjs, delObjs) {
			let addFilters = [];
			let delFilters = [];
			
			for(let oid in addObjs) {
				// 对象本身及对象下属子对象的事件将会被订阅
				addFilters.push(addObjs[oid].eventTopicPath + "#");
			}
			for(let oid in delObjs) {
				// 对象及其下属子对象的事件将会被取消订阅
				delFilters.push(delObjs[oid].eventTopicPath + "#");
			}
			
			return this.rpcLink.subscribeEx(addFilters, delFilters);
		}
		
		/**
		 * 获取本网关的核心对象的配置参数
		 * @param {int} oid 核心对象OID
		 * @return {Promise} 返回一个异步结果对象
		 */
		getObjConfig(oid) {
			return this.rpc("obj.getConfig", {oid: oid});
		}
	}

	(function() {
		return (typeof global !== "undefined") ? global :
			(typeof self !== "undefined") ? self :
			(typeof window !== "undefined") ? window : {};
	})()["GatewayAgent"] = GatewayAgent;
}
